﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Xml.Serialization;
using Commons.Collections;
using NVelocity;
using NVelocity.App;

namespace MaxZhang.EasyEntities.EasyDesigner.Core
{
    [Serializable]
    public class DomainModel
    {
        public DomainModel()
        {
            IsNew = true;
            IsOpen = true;
            IsClose = false;
            IsFilterKey = false;
            IsFilterNoCfg = false;
            Entities = new List<string>();
            DbEntitys = new ObservableCollection<DbEntity>();
        }

         public DomainModel(string path):this()
         {
             this.FileName = path;
         }

        [XmlIgnore]
        public bool IsNew { set; get; }
        [XmlIgnore]
        public bool IsOpen { set; get; }
        [XmlIgnore]
        public bool IsClose { set; get; }

         [XmlIgnore]
        public bool IsFilterKey;
         [XmlIgnore]
        public bool IsFilterNoCfg;


        [XmlIgnore]
        public ObservableCollection<DbEntity> DbEntitys { set; get; }

        [XmlIgnore]
        public ICollectionView DataView
        {
            get
            {

                return CollectionViewSource.GetDefaultView(this.DbEntitys);
            }
        }

        [XmlArray("Entities")]
        public List<string> Entities { set; get; }

        [XmlIgnore]
        public string FileName { set; get; }

        public static DomainModel Open(string file)
        {
            return new DomainModel(file);
        }

      
     

        public bool UpdateForDataBase()
        {
            return false;
        }


        public List<DbEntity> GetTables()
        {

            string connString = ConfigurationSettings.AppSettings["connectionString"];
            IDbSchema ds = new SqlServerDbSchema(connString);
            var ts = ds.GetTables();
            this.DbEntitys = new ObservableCollection<DbEntity>(ts);
            return ts;
        }

        public bool Open()
        {
            string dir = System.IO.Path.GetDirectoryName(this.FileName);
            string path = this.FileName;
            string xml = File.ReadAllText(path);
            var dm = xml.Deserialize<DomainModel>();
            foreach (var es in dm.Entities)
            {
                string enxml = File.ReadAllText(System.IO.Path.Combine(dir,es));
                var entity = enxml.Deserialize<DbEntity>();
                foreach (var p in entity.Propertys)
                {
                    p.PropertyType = Type.GetType(p.PropertyTypeName);
                }
                this.DbEntitys.Add(entity);
            }
            
            return true;
        }



        public void Save()
        {
            VelocityEngine velocity = new VelocityEngine();

            ExtendedProperties props = new ExtendedProperties();
            velocity.Init(props);
            Template template = velocity.GetTemplate(@"codeTemplate.vm");
            VelocityContext context = new VelocityContext();
            


          

            var fileName = this.FileName;
            string dir = System.IO.Path.GetDirectoryName(fileName);
           StringBuilder sb = new StringBuilder();
            sb.AppendLine("using System;");
            sb.AppendLine("using MaxZhang.EasyEntities.Persistence.Mapping;");
            sb.AppendLine("namespace EasyEntities.Models");
            sb.AppendLine("{");
            foreach (var entity in DbEntitys)
            {
                if (entity.Name.StartsWith("UQTAB"))
                    continue;
                context.Put("entity", entity);
                StringWriter writer = new StringWriter();
                template.Merge(context, writer);
                sb.AppendLine(writer.GetStringBuilder().ToString());

                this.Entities.Add(entity.Name + ".xml");
                string enxml = entity.Serializer();
                File.WriteAllText(dir + @"\" + entity.Name + ".xml",enxml);
            }
            sb.AppendLine("}");
            string tabxml = this.Serializer();
            File.WriteAllText(fileName, tabxml);
            File.WriteAllText(System.IO.Path.Combine(dir, "Domain.cs"), sb.ToString());
        }

    }
}
